ZK 5.0 and jQuery part 2 fr
Introduction
ZK5 utilise jQuery coté client, offrant un large panel de possibilités. Un des plus grands bénéfices à utiliser jQuery est qu'il existe un nombre important d'excellents plug-ins. Dans ce document, nous allons montrer l'implémentation d'un effet coté client en utilisant le plug-in jQuery UI Tools qui propose des animations, des abstractions pour des interactions bas-niveau et bien plus encore.
Ce doucment est le second d'une série de 2 documents. La première partie est disponible ici et propose l'implémentation d'un effet plus simple.
Description du fichier ZUL
Le fichier ZUL est composé de 3 parties. Nous trouvons premièrement le script coté client, qui se trouve dans les balises <script> et la directive du script (<?script src=... ?>).
<!-- CLIENT SIDE FUNCTIONALITY! -->
<?script src="jquery-ui-1.7.2.custom.min.js"?>
<script>
<![CDATA[
function updateWithExplosion (value, fromServer, updateColor) {
if(this.desktop) {
jq(this).effect("explode",
{},
500);
}
this.$setValue(value, fromServer);
if (this.desktop) {
if (updateColor) {
jq(this.getCaveNode().parentNode.parentNode).css({background: ((value<0) ? 'red':'green')});
this.setStyle('color: #FFFFFF');
}
jq(this).show("drop", {direction : "up"}, 1000);
}
}
function updateWithColorAndExplosion (value, fromServer) {
updateWithExplosion.call(this, value, fromServer, true);
}
]]>
</script>
Ensuite, le code coté serveur se trouve dans les balises <zscript>. Attention que celles-ci peuvent être facilement confondus avec les balises <script>.
<!-- SERVER SIDE FUNCTIONALITY! -->
<zscript>
<![CDATA[
public void updateStocks() {
Object[] values = getStockValues();
Label stockPrice = stockGrid.getFellow(values[0]);
Label stockDifference = stockGrid.getFellow(values[1]);
int newValue = ((Number)values[2]).intValue();
int difference = newValue - Integer.parseInt(stockPrice.getValue());
stockPrice.setValue(Long.toString(newValue));
stockDifference.setValue(Long.toString(difference));
}
public Object[] getStockValues() {
int randomControl = (int)Math.ceil(Math.random() * 3);
return new Object[] {"stockPrice" + randomControl,
"stockDifference" + randomControl,
(int)Math.ceil((Math.random() * 10) + 95)};
}
]]>
</zscript>
Enfin, nous trouvons la balise ZUML qui décrit le GUI.
<!-- ZUL MARKUP (UI IMPLEMENTATION!) -->
<timer id="updateTimer" delay="3000" repeats="true" onTimer="updateStocks()" />
<grid id="stockGrid" fixedLayout="true">
<columns>
<column label="Stock name" />
<column label="Stock value" />
<column label="Stock difference" />
</columns>
<rows>
<row>
<label id="stockName1" value="Ultra Corp: " />
<label id="stockPrice1" value="100" w:setValue="updateWithExplosion"/>
<label id="stockDifference1" value="0" w:setValue="updateWithColorAndExplosion"/>
</row>
<row>
<label id="stockName2" value="Amazing Corp: " />
<label id="stockPrice2" value="100" w:setValue="updateWithExplosion"/>
<label id="stockDifference2" value="0" w:setValue="updateWithColorAndExplosion"/>
</row>
<row>
<label id="stockName3" value="Great Corp: " />
<label id="stockPrice3" value="100" w:setValue="updateWithExplosion"/>
<label id="stockDifference3" value="0" w:setValue="updateWithColorAndExplosion"/>
</row>
</rows>
</grid>
Le but de l'application
Le but de cette application est de démontrer les fonctionnalités jQuery dans ZK 5 et à quoi cela peut servir. Dans cet exemple, nous illustrons comment surcharger la fonction setValue de certains composants chez le client. En faisant cela, nous pouvons ajouter des effets aux données lorsque ces dernières changent. Ces données peuvent être définies par le serveur ou par le client. Dans cet exemple, les données sont fournies par javascript au client.
Démo
Développer cet exemple
Pour commencer, nous devons inclure jQuery UI dans la page, ce qui est fait grâce au composant script de ZK.
<?script src="/scripts/tools.expose-1.0.3.js"?>
Nous pouvons dès lors utiliser les méthodes fournies par la librairie jQuery.
La fonction setValue
La fonction setValue est utilisée pour changer la valeur d'un Label. Si nous voulons appliquer un effet spécial à cette valeur lorsqu'elle change, nous devons surcharger la fonction setValue chez le client.
Surcharger la fonction setValue chez le client
Utiliser un namespace coté client
Lorsque des fonctionnalités sont implémentées coté client, il est nécessaire de déclarer un namespace. En faisant cela, les évènements seront gérés du coté client et non du coté serveur. Sans ce namespace, ZK va penser que votre code est du code Java et qu'il devrait être exécuté du coté serveur.
Définir un namespace
Définir un namespace est facile, il suffit d'ajouter le code suivant comme attribut de n'importe quelle balise ZK
xmlns:w=http://www.zkoss.org/2005/zk/client
Dans notre exemple, nous l'avons ajouté dans la balise ZK de sorte que le namespace soit disponible pour tous les composants.
<zk xmlns:w="http://www.zkoss.org/2005/zk/client">
Surcharger la fonction setValue
Dans cet exemple, nous utilisons des Labels pour afficher les informations. Par conséquent, nous devons surcharger la méthode setValue des labels. Pour le faire, nous déclarons un attribut setValue. Le code se trouve ci-après. Remarquez que l'attribut est précédé de w: qui est le nom de notre namespace.
<label id="stockPrice1" value="100" w:setValue="updateWithExplosion"/>
Créer les fonctions de surcharge
Deux fonctions sont utilisées dans cet exemple: la première est la fonction updateWithExplosion et la seconde est la fonction updateWithColorAndExplosion. Pour surcharger setValue, nous devons écrire une fonction avec le squelette suivant:
function NAME (value, fromServer) {
this.$setValue(value, fromServer);
if (this.desktop) {
jq(this).WHATEVER_EFFECT
}
}
Les structures des 2 fonctions diffèrent par le fait qu'une des deux prends un argument en plus que l'autre, mais cela ne change en rien le mécanisme de surcharge. Par exemple, updateExplosion requiert un argument de plus. Quand cette méthode est utilisée pour surcharger la fonction setValue, le paramètre “updateColor” restera indéfini.
function updateWithExplosion (value, fromServer, updateColor) {
if(this.desktop) {
jq(this).effect("explode",
{},
500);
}
this.$setValue(value, fromServer);
if (this.desktop) {
if (updateColor) {
jq(this.getCaveNode().parentNode.parentNode).css({background: ((value<0) ? 'red':'green')});
this.setStyle('color: #FFFFFF');
}
jq(this).show("drop", {direction : "up"}, 1000);
}
}
Le code ci-dessous montre que si le troisième paramètre passé est à true, alors la couleur de la cellule est changée. Ceci est fait grâce à la fonction updateWithColorAndExplosion:
function updateWithColorAndExplosion (value, fromServer) {
updateWithExplosion.call(this, value, fromServer, true);
}
Cette méthode est intéressante dans la mesure où elle utilise la méthode javascript call pour exécuter updateWithExplosion. Vous pouvez aussi remarquer que le premier paramètre du call est “ this.” “this” dépend du champ d'application, dans ce cas-ci, “this” doit être préservé comme widget. Si ce call n'était pas effectué, le type de “this” dans la fonction updateWithExplosion deviendrait l'objet script.
Mettre à jour les données
Les données sont mises à jour par l'intérmédiare d'un composant timer et d'un code se trouvant coté serveur. Au chargement de la page, le timer va démarrer et, toutes les 3 secondes, la fonction updateStocks() sera appelée. Elle pourra alors mettre à jour les stocks et envoyer les nouvelles informations au client.
<timer id="updateTimer" delay="3000" repeats="true" onTimer="updateStocks()" />
public void updateStocks() {
Object[] values = getStockValues();
Label stockPrice = stockGrid.getFellow(values[0]);
Label stockDifference = stockGrid.getFellow(values[1]);
int newValue = ((Number)values[2]).intValue();
int difference = newValue - Integer.parseInt(stockPrice.getValue());
stockPrice.setValue(Long.toString(newValue));
stockDifference.setValue(Long.toString(difference));
}
public Object[] getStockValues() {
int randomControl = (int)Math.ceil(Math.random() * 3);
return new Object[] {"stockPrice" + randomControl,
"stockDifference" + randomControl,
(int)Math.ceil((Math.random() * 10) + 95)};
}
Dans une application réelle, ces données seraient récupérées depuis une base de données et le timer serait remplacé par le mécanisme d'envoie des données du serveur. Merci de regarder ici pour plus de détails.
Source
Téléchargez le code source ici
See Also
ZK 5.0 and jQuery part 2 (English)